package cn.edu.scau.cmi.hombio.service;

import cn.edu.scau.cmi.hombio.dao.CureMedicineDAO;
import cn.edu.scau.cmi.hombio.dao.CureTaskMedicineDAO;
import cn.edu.scau.cmi.hombio.dao.FodderTypeDAO;
import cn.edu.scau.cmi.hombio.dao.PreventionTypeDAO;
import cn.edu.scau.cmi.hombio.dao.UnitDAO;

import cn.edu.scau.cmi.hombio.domain.CureMedicine;
import cn.edu.scau.cmi.hombio.domain.CureTaskMedicine;
import cn.edu.scau.cmi.hombio.domain.FodderType;
import cn.edu.scau.cmi.hombio.domain.PreventionType;
import cn.edu.scau.cmi.hombio.domain.Unit;

import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

/**
 * Spring service that handles CRUD requests for Unit entities
 * 
 */

@Service("UnitService")

@Transactional
public class UnitServiceImpl implements UnitService {

	/**
	 * DAO injected by Spring that manages CureMedicine entities
	 * 
	 */
	@Autowired
	private CureMedicineDAO cureMedicineDAO;

	/**
	 * DAO injected by Spring that manages CureTaskMedicine entities
	 * 
	 */
	@Autowired
	private CureTaskMedicineDAO cureTaskMedicineDAO;

	/**
	 * DAO injected by Spring that manages FodderType entities
	 * 
	 */
	@Autowired
	private FodderTypeDAO fodderTypeDAO;

	/**
	 * DAO injected by Spring that manages PreventionType entities
	 * 
	 */
	@Autowired
	private PreventionTypeDAO preventionTypeDAO;

	/**
	 * DAO injected by Spring that manages Unit entities
	 * 
	 */
	@Autowired
	private UnitDAO unitDAO;

	/**
	 * Instantiates a new UnitServiceImpl.
	 *
	 */
	public UnitServiceImpl() {
	}

	/**
	 * Return all Unit entity
	 * 
	 */
	@Transactional
	public List<Unit> findAllUnits(Integer startResult, Integer maxRows) {
		return new java.util.ArrayList<Unit>(unitDAO.findAllUnits(startResult, maxRows));
	}

	/**
	 * Delete an existing PreventionType entity
	 * 
	 */
	@Transactional
	public Unit deleteUnitPreventionTypesForReportUnitId(Integer unit_id, Integer related_preventiontypesforreportunitid_id) {
		PreventionType related_preventiontypesforreportunitid = preventionTypeDAO.findPreventionTypeByPrimaryKey(related_preventiontypesforreportunitid_id, -1, -1);

		Unit unit = unitDAO.findUnitByPrimaryKey(unit_id, -1, -1);

		related_preventiontypesforreportunitid.setUnitByUnitId(null);
		unit.getPreventionTypesForUnitId().remove(related_preventiontypesforreportunitid);

		preventionTypeDAO.remove(related_preventiontypesforreportunitid);
		preventionTypeDAO.flush();

		return unit;
	}

	/**
	 * Delete an existing PreventionType entity
	 * 
	 */
	@Transactional
	public Unit deleteUnitPreventionTypesForUnitId(Integer unit_id, Integer related_preventiontypesforunitid_id) {
		PreventionType related_preventiontypesforunitid = preventionTypeDAO.findPreventionTypeByPrimaryKey(related_preventiontypesforunitid_id, -1, -1);

		Unit unit = unitDAO.findUnitByPrimaryKey(unit_id, -1, -1);

		related_preventiontypesforunitid.setUnitByUnitId(null);
		unit.getPreventionTypesForUnitId().remove(related_preventiontypesforunitid);

		preventionTypeDAO.remove(related_preventiontypesforunitid);
		preventionTypeDAO.flush();

		return unit;
	}

	/**
	 * Load an existing Unit entity
	 * 
	 */
	@Transactional
	public Set<Unit> loadUnits() {
		return unitDAO.findAllUnits();
	}

	/**
	 * Delete an existing FodderType entity
	 * 
	 */
	@Transactional
	public Unit deleteUnitFodderTypes(Integer unit_id, Integer related_foddertypes_id) {
		FodderType related_foddertypes = fodderTypeDAO.findFodderTypeByPrimaryKey(related_foddertypes_id, -1, -1);

		Unit unit = unitDAO.findUnitByPrimaryKey(unit_id, -1, -1);

		related_foddertypes.setUnit(null);
		unit.getFodderTypes().remove(related_foddertypes);

		fodderTypeDAO.remove(related_foddertypes);
		fodderTypeDAO.flush();

		return unit;
	}

	/**
	 * Save an existing Unit entity
	 * 
	 */
	@Transactional
	public void saveUnit(Unit unit) {
		Unit existingUnit = unitDAO.findUnitByPrimaryKey(unit.getId());

		if (existingUnit != null) {
			if (existingUnit != unit) {
				existingUnit.setId(unit.getId());
				existingUnit.setName(unit.getName());
				existingUnit.setMemo(unit.getMemo());
			}
			unit = unitDAO.store(existingUnit);
		} else {
			unit = unitDAO.store(unit);
		}
		unitDAO.flush();
	}

	/**
	 * Save an existing CureTaskMedicine entity
	 * 
	 */
	@Transactional
	public Unit saveUnitCureTaskMedicines(Integer id, CureTaskMedicine related_curetaskmedicines) {
		Unit unit = unitDAO.findUnitByPrimaryKey(id, -1, -1);
		CureTaskMedicine existingcureTaskMedicines = cureTaskMedicineDAO.findCureTaskMedicineByPrimaryKey(related_curetaskmedicines.getId());

		// copy into the existing record to preserve existing relationships
		if (existingcureTaskMedicines != null) {
			existingcureTaskMedicines.setId(related_curetaskmedicines.getId());
			existingcureTaskMedicines.setQuantity(related_curetaskmedicines.getQuantity());
			existingcureTaskMedicines.setMemo(related_curetaskmedicines.getMemo());
			related_curetaskmedicines = existingcureTaskMedicines;
		}

		related_curetaskmedicines.setUnit(unit);
		unit.getCureTaskMedicines().add(related_curetaskmedicines);
		related_curetaskmedicines = cureTaskMedicineDAO.store(related_curetaskmedicines);
		cureTaskMedicineDAO.flush();

		unit = unitDAO.store(unit);
		unitDAO.flush();

		return unit;
	}

	/**
	 * Delete an existing CureTaskMedicine entity
	 * 
	 */
	@Transactional
	public Unit deleteUnitCureTaskMedicines(Integer unit_id, Integer related_curetaskmedicines_id) {
		CureTaskMedicine related_curetaskmedicines = cureTaskMedicineDAO.findCureTaskMedicineByPrimaryKey(related_curetaskmedicines_id, -1, -1);

		Unit unit = unitDAO.findUnitByPrimaryKey(unit_id, -1, -1);

		related_curetaskmedicines.setUnit(null);
		unit.getCureTaskMedicines().remove(related_curetaskmedicines);

		cureTaskMedicineDAO.remove(related_curetaskmedicines);
		cureTaskMedicineDAO.flush();

		return unit;
	}

	/**
	 */
	@Transactional
	public Unit findUnitByPrimaryKey(Integer id) {
		return unitDAO.findUnitByPrimaryKey(id);
	}

	/**
	 * Save an existing CureMedicine entity
	 * 
	 */
	@Transactional
	public Unit saveUnitCureMedicines(Integer id, CureMedicine related_curemedicines) {
		Unit unit = unitDAO.findUnitByPrimaryKey(id, -1, -1);
		CureMedicine existingcureMedicines = cureMedicineDAO.findCureMedicineByPrimaryKey(related_curemedicines.getId());

		// copy into the existing record to preserve existing relationships
		if (existingcureMedicines != null) {
			existingcureMedicines.setId(related_curemedicines.getId());
			existingcureMedicines.setQuantity(related_curemedicines.getQuantity());
			existingcureMedicines.setMemo(related_curemedicines.getMemo());
			related_curemedicines = existingcureMedicines;
		}

		related_curemedicines.setUnit(unit);
		unit.getCureMedicines().add(related_curemedicines);
		related_curemedicines = cureMedicineDAO.store(related_curemedicines);
		cureMedicineDAO.flush();

		unit = unitDAO.store(unit);
		unitDAO.flush();

		return unit;
	}

	/**
	 * Save an existing FodderType entity
	 * 
	 */
	@Transactional
	public Unit saveUnitFodderTypes(Integer id, FodderType related_foddertypes) {
		Unit unit = unitDAO.findUnitByPrimaryKey(id, -1, -1);
		FodderType existingfodderTypes = fodderTypeDAO.findFodderTypeByPrimaryKey(related_foddertypes.getId());

		// copy into the existing record to preserve existing relationships
		if (existingfodderTypes != null) {
			existingfodderTypes.setId(related_foddertypes.getId());
			existingfodderTypes.setName(related_foddertypes.getName());
			existingfodderTypes.setSupply(related_foddertypes.getSupply());
			existingfodderTypes.setMemo(related_foddertypes.getMemo());
			related_foddertypes = existingfodderTypes;
		} else {
			related_foddertypes = fodderTypeDAO.store(related_foddertypes);
			fodderTypeDAO.flush();
		}

		related_foddertypes.setUnit(unit);
		unit.getFodderTypes().add(related_foddertypes);
		related_foddertypes = fodderTypeDAO.store(related_foddertypes);
		fodderTypeDAO.flush();

		unit = unitDAO.store(unit);
		unitDAO.flush();

		return unit;
	}

	/**
	 * Save an existing PreventionType entity
	 * 
	 */
	@Transactional
	public Unit saveUnitPreventionTypesForUnitId(Integer id, PreventionType related_preventiontypesforunitid) {
		Unit unit = unitDAO.findUnitByPrimaryKey(id, -1, -1);
		PreventionType existingpreventionTypesForUnitId = preventionTypeDAO.findPreventionTypeByPrimaryKey(related_preventiontypesforunitid.getId());

		// copy into the existing record to preserve existing relationships
		if (existingpreventionTypesForUnitId != null) {
			existingpreventionTypesForUnitId.setId(related_preventiontypesforunitid.getId());
			existingpreventionTypesForUnitId.setName(related_preventiontypesforunitid.getName());
			existingpreventionTypesForUnitId.setReportQuality(related_preventiontypesforunitid.getReportQuality());
			existingpreventionTypesForUnitId.setQuality(related_preventiontypesforunitid.getQuality());
			existingpreventionTypesForUnitId.setMemo(related_preventiontypesforunitid.getMemo());
			related_preventiontypesforunitid = existingpreventionTypesForUnitId;
		}

		related_preventiontypesforunitid.setUnitByUnitId(unit);
		unit.getPreventionTypesForUnitId().add(related_preventiontypesforunitid);
		related_preventiontypesforunitid = preventionTypeDAO.store(related_preventiontypesforunitid);
		preventionTypeDAO.flush();

		unit = unitDAO.store(unit);
		unitDAO.flush();

		return unit;
	}

	/**
	 * Delete an existing CureMedicine entity
	 * 
	 */
	@Transactional
	public Unit deleteUnitCureMedicines(Integer unit_id, Integer related_curemedicines_id) {
		CureMedicine related_curemedicines = cureMedicineDAO.findCureMedicineByPrimaryKey(related_curemedicines_id, -1, -1);

		Unit unit = unitDAO.findUnitByPrimaryKey(unit_id, -1, -1);

		related_curemedicines.setUnit(null);
		unit.getCureMedicines().remove(related_curemedicines);

		cureMedicineDAO.remove(related_curemedicines);
		cureMedicineDAO.flush();

		return unit;
	}

	/**
	 * Delete an existing Unit entity
	 * 
	 */
	@Transactional
	public void deleteUnit(Unit unit) {
		unitDAO.remove(unit);
		unitDAO.flush();
	}

	/**
	 * Return a count of all Unit entity
	 * 
	 */
	@Transactional
	public Integer countUnits() {
		return ((Long) unitDAO.createQuerySingleResult("select count(o) from Unit o").getSingleResult()).intValue();
	}

	/**
	 * Save an existing PreventionType entity
	 * 
	 */
	@Transactional
	public Unit saveUnitPreventionTypesForReportUnitId(Integer id, PreventionType related_preventiontypesforreportunitid) {
		Unit unit = unitDAO.findUnitByPrimaryKey(id, -1, -1);
		PreventionType existingpreventionTypesForReportUnitId = preventionTypeDAO.findPreventionTypeByPrimaryKey(related_preventiontypesforreportunitid.getId());

		// copy into the existing record to preserve existing relationships
		if (existingpreventionTypesForReportUnitId != null) {
			existingpreventionTypesForReportUnitId.setId(related_preventiontypesforreportunitid.getId());
			existingpreventionTypesForReportUnitId.setName(related_preventiontypesforreportunitid.getName());
			existingpreventionTypesForReportUnitId.setReportQuality(related_preventiontypesforreportunitid.getReportQuality());
			existingpreventionTypesForReportUnitId.setQuality(related_preventiontypesforreportunitid.getQuality());
			existingpreventionTypesForReportUnitId.setMemo(related_preventiontypesforreportunitid.getMemo());
			related_preventiontypesforreportunitid = existingpreventionTypesForReportUnitId;
		}

		related_preventiontypesforreportunitid.setUnitByUnitId(unit);
		unit.getPreventionTypesForUnitId().add(related_preventiontypesforreportunitid);
		related_preventiontypesforreportunitid = preventionTypeDAO.store(related_preventiontypesforreportunitid);
		preventionTypeDAO.flush();

		unit = unitDAO.store(unit);
		unitDAO.flush();

		return unit;
	}
}
